﻿#include "tcpsession.h"
extern "C"
{
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
}
#include "mydb.h"

TcpSession::TcpSession(clientData *cd) : cd(cd)
{
}

TcpSession::~TcpSession()
{
    // closeConnect();
}

void TcpSession::run()
{
    int rdSize = 0;
    string msg;
    while (1)
    {
        char lenBuf[9] = {0};
        // 每次取8个字节长度
        rdSize = recv(cd->clientFd, lenBuf, 8, 0);
        // 客户端断开连接
        if (rdSize <= 0)
        {
            cout << "clientFd=" << cd->clientFd << ",ip=" << cd->ip << ",port=" << cd->port << ",断开连接" << endl;
            closeConnect();
            delete this;
            return;
        }
        int len = atoi(lenBuf);
        cout << "msg len:" << len << endl;
        if (len <= 0)
        {
            continue;
        }
        // 保存数据缓冲区
        char data[len + 1];
        memset(data, 0, len + 1);

        rdSize = recv(cd->clientFd, data, len, 0); // 从客户端接收数据
        msg = data;
        cout << "msg::" << msg << endl;
        switch (getValueInt(&msg, "msg_type"))
        {
        case MSG_QUIT:
        {
            closeConnect();
            delete this;
            return;
        }
        case MSG_EXIT:
        {
            closeConnect();
            delete this;
            return;
        }
        case MSG_ATT_INSERT_RECORD:
        {
            insertAttendanceRecord(msg);
            break;
        }
        case MSG_ATT_INFO_LIST:
        {
            getAttendanceInfoList(msg);
            break;
        }
        case MSG_USER_REGISTER:
        {
            userRegister(msg);
            break;
        }
        case MSG_USER_INFO_LIST:
        {
            getUserInfoList(msg);
            break;
        }
        case MSG_USER_INFO_COUNT:
        {
            getUserInfoCount(msg);
            break;
        }
        case MSG_USER_DELETE:
        {
            userDelete(msg);
            break;
        }
        default:
            break;
        }

        displayAllClient(); // 打印全部客户端信息
    }
}

void TcpSession::closeConnect()
{
    pthread_mutex_lock(&mutex); // 加锁
    close(cd->clientFd);
    for (int i = 0; i < (int)clientArray->size(); i++)
    {
        if ((*clientArray)[i]->clientId == cd->clientId)
        {
            clientArray->erase(clientArray->begin() + i); // 删除指定位置元素
            delete cd;
        }
    }
    pthread_mutex_unlock(&mutex); // 解锁
}

void TcpSession::displayAllClient()
{
    cout << "=============displayAllClient=============" << endl;
    for (int i = 0; i < (int)clientArray->size(); i++)
    {
        cout << "clientFd=" << (*clientArray)[i]->clientFd << endl;
        cout << "ip=" << (*clientArray)[i]->ip << endl;
        cout << "port=" << (*clientArray)[i]->port << endl;
        cout << endl;
    }
    cout << "=============displayAllClient=============" << endl;
}

string TcpSession::getValueStr(string *msg, const char *key)
{
    string err;
    auto json = Json::parse(*msg, err);
    return json[key].string_value();
}

int TcpSession::getValueInt(string *msg, const char *key)
{
    string err;
    auto json = Json::parse(*msg, err);
    return json[key].int_value();
}

// 服务器单发数据
void TcpSession::serverSingleMsg(string &msg)
{
    send(cd->clientFd, msg.c_str(), msg.length(), 0); // 向其他客户端发送数据
}

bool TcpSession::isSameDay(string &targetTime, string &date)
{
    if (targetTime.find(date) == string::npos) // 没找到
    {
        return false;
    }
    else
    {
        return true;
    }
}

void TcpSession::getSamedayAttendance(string &json)
{
    string user_id = getValueStr(&json, "user_id");
}

void TcpSession::insertAttendanceRecord(string &json)
{
    string user_id = getValueStr(&json, "user_id");
    int att_way = getValueInt(&json, "att_way");
    string face_pic_path = getValueStr(&json, "face_pic_path");
    string create_time = getValueStr(&json, "create_time");

    string sql = "INSERT INTO attendance_record(user_id,att_way,face_pic_path,create_time) "
                 "VALUES('" +
                 user_id + "'," + to_string(att_way) + ",'" + face_pic_path + "','" + create_time + "');";

    cout << "insert user_info :" << sql << endl;
    int result = MSG_RESULT_SUCCESS;
    if (!MyDB::getDB()->updateData(&sql))
    {
        cout << "insert user_info error:" << sql << endl;
        result = MSG_RESULT_ERROR;
    }

    // 查打卡数据总数
    sql = "select count(*) from attendance_record;";
    string countData;
    MyDB::getDB()->selectData(&sql, &countData);

    string err;
    Json arrJson = Json::parse(countData, err);
    string count;

    for (const Json &k : arrJson.array_items())
    {
        count = k["count(*)"].string_value();
        break;
    }

    string msg = "{\"type\":" + to_string(MSG_ATT_INSERT_RECORD) + ",\"data\":{\"result\":" + to_string(result) + ",\"count\":" + count + ",\"create_time\":\"" + create_time + "\"}}";
    serverSingleMsg(msg);
    cout << "userRegister:" << msg << endl;
}

void TcpSession::getAttendanceInfoList(string &json)
{
    // 查用户数据
    int page = getValueInt(&json, "page");
    int page_size = getValueInt(&json, "page_size");
    string username = getValueStr(&json, "username");
    string start_time = getValueStr(&json, "start_time");
    string end_time = getValueStr(&json, "end_time");
    int startPos = (page - 1) * page_size;
    string sql_where = "where 1 = 1";
    if (!username.empty())
    {
        sql_where += " and u.username = '" + username + "' ";
    }
    if (!start_time.empty())
    {
        sql_where += " and a.create_time >= '" + start_time + "' ";
    }
    if (!end_time.empty())
    {
        if (sql_where.find("create_time") != -1)
        {
            sql_where += " and ";
        }
        sql_where += " a.create_time <= '" + end_time + "' ";
    }
    string sql = "select a.*,u.username from attendance_record a left join user_info u on a.user_id = u.user_id " + sql_where + " limit " + to_string(startPos) + "," + to_string(page_size) + ";";
    string attendanceInfoList;
    cout << "getAttendanceInfoList sql:" << sql << endl;
    MyDB::getDB()->selectData(&sql, &attendanceInfoList);

    // 查用户数据总数
    sql = "select count(*) from attendance_record a left join user_info u on a.user_id = u.user_id " + sql_where + ";";
    cout << "getAttendanceInfoList sql2:" << sql << endl;
    string countData;
    MyDB::getDB()->selectData(&sql, &countData);

    string err;
    Json arrJson = Json::parse(countData, err);
    string count;

    for (const Json &k : arrJson.array_items())
    {
        count = k["count(*)"].string_value();
        break;
    }

    string msg = "{\"type\":" + to_string(MSG_ATT_INFO_LIST) +
                 ",\"data\":{\"count\":" + count + ",\"attendanceInfoList\":" + attendanceInfoList + "}}";
    serverSingleMsg(msg);
    cout << "getAttendanceInfoList data:" << msg << endl;
}

void TcpSession::userRegister(string &json)
{
    string user_id = getValueStr(&json, "user_id");
    string username = getValueStr(&json, "username");
    string pic_path = getValueStr(&json, "pic_path");
    string rfid_card_no = getValueStr(&json, "rfid_card_no");
    string create_time = getValueStr(&json, "create_time");

    // 存在则修改,不存在则插入,判断存在条件为主键
    string sql = "REPLACE INTO user_info(user_id,username,pic_path,rfid_card_no,create_time) "
                 "VALUES('" +
                 user_id + "','" + username + "','" + pic_path + "','" + rfid_card_no + "','" + create_time + "');";

    cout << "insert user_info :" << sql << endl;

    int result = MSG_RESULT_SUCCESS;
    if (!MyDB::getDB()->updateData(&sql))
    {
        cout << "insert user_info error:" << sql << endl;
        result = MSG_RESULT_ERROR;
    }

    sql = "INSERT INTO user_face_base(user_id,face_pic_path,create_time) "
          "VALUES('" +
          user_id + "','" + pic_path + "','" + create_time + "');";

    cout << "insert user_face_base :" << sql << endl;

    if (result != MSG_RESULT_ERROR && !MyDB::getDB()->updateData(&sql))
    {
        cout << "insert user_face_base error:" << sql << endl;
        result = MSG_RESULT_ERROR;
    }

    // 查用户数据总数
    sql = "select count(*) from user_info;";
    string countData;
    MyDB::getDB()->selectData(&sql, &countData);

    string err;
    Json arrJson = Json::parse(countData, err);
    string count;

    for (const Json &k : arrJson.array_items())
    {
        count = k["count(*)"].string_value();
        break;
    }

    string msg = "{\"type\":" + to_string(MSG_USER_REGISTER) + ",\"data\":{\"count\":" + count + ",\"result\":" + to_string(result) + "}}";
    serverSingleMsg(msg);
    cout << "userRegister:" << msg << endl;
}

void TcpSession::getUserInfoList(string &json)
{
    // 查用户数据
    int page = getValueInt(&json, "page");
    int page_size = getValueInt(&json, "page_size");
    string username = getValueStr(&json, "username");
    string start_time = getValueStr(&json, "start_time");
    string end_time = getValueStr(&json, "end_time");
    int startPos = (page - 1) * page_size;
    string sql_where = "where 1 = 1";
    if (!username.empty())
    {
        sql_where += " and username = '" + username + "' ";
    }
    if (!start_time.empty())
    {
        sql_where += " and create_time >= '" + start_time + "' ";
    }
    if (!end_time.empty())
    {
        if (sql_where.find("create_time") != -1)
        {
            sql_where += " and ";
        }
        sql_where += " create_time <= '" + end_time + "' ";
    }
    string sql = "select * from user_info " + sql_where + " limit " + to_string(startPos) + "," + to_string(page_size) + ";";
    string userInfoList;
    cout << "getUserInfoList sql:" << sql << endl;
    MyDB::getDB()->selectData(&sql, &userInfoList);

    // 查用户数据总数
    sql = "select count(*) from user_info " + sql_where + ";";
    string countData;
    MyDB::getDB()->selectData(&sql, &countData);

    string err;
    Json arrJson = Json::parse(countData, err);
    string count;

    for (const Json &k : arrJson.array_items())
    {
        count = k["count(*)"].string_value();
        break;
    }

    string msg = "{\"type\":" + to_string(MSG_USER_INFO_LIST) +
                 ",\"data\":{\"count\":" + count + ",\"userInfoList\":" + userInfoList + "}}";
    serverSingleMsg(msg);
    cout << "getUserInfoList data:" << msg << endl;
}

void TcpSession::getUserInfoCount(string &json)
{
    string sql = "select count(*) from user_info;";
    string countData;
    MyDB::getDB()->selectData(&sql, &countData);

    string err;
    Json arrJson = Json::parse(countData, err);
    string count;

    for (const Json &k : arrJson.array_items())
    {
        count = k["count(*)"].string_value();
        break;
    }

    string msg = "{\"type\":" + to_string(MSG_USER_INFO_COUNT) + ",\"data\":{\"count\":" + count + "}}";
    serverSingleMsg(msg);
    cout << "getuserInfoCount data:" << msg << endl;
}

void TcpSession::userDelete(string &json)
{
    string user_id = getValueStr(&json, "user_id");
    string sql = "delete from user_info where user_id = '" + user_id + "';";

    int result = MSG_RESULT_SUCCESS;
    if (!MyDB::getDB()->updateData(&sql))
    {
        cout << "userDelete error:" << sql << endl;
        result = MSG_RESULT_ERROR;
    }

    sql = "delete from user_face_base where user_id = '" + user_id + "';";
    if (!MyDB::getDB()->updateData(&sql))
    {
        cout << "userDelete error:" << sql << endl;
        result = MSG_RESULT_ERROR;
    }

    // 查用户数据总数
    sql = "select count(*) from user_info;";
    string countData;
    MyDB::getDB()->selectData(&sql, &countData);

    string err;
    Json arrJson = Json::parse(countData, err);
    string count;

    for (const Json &k : arrJson.array_items())
    {
        count = k["count(*)"].string_value();
        break;
    }

    string msg = "{\"type\":" + to_string(MSG_USER_DELETE) + ",\"data\":{\"count\":" + count + ",\"result\":" + to_string(result) + "}}";
    serverSingleMsg(msg);
    cout << "userDelete data:" << msg << endl;
}